package com.minglead.crawler.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileUtils {

    public static String getFileContent(File file) {
        return getFileContent(file, -1L, -1L);
    }

    public static String getFileContent(File file, Long offset, Long byteNum) {
        StringBuffer s = new StringBuffer("");
        BufferedReader reader = null;
        FileReader fileReader = null;
        try {
            offset = offset == null || offset < 0 ? 0 : offset;
            byteNum = byteNum == null || byteNum < 0 ? 0 : (128 * 1024L);//128kb
            fileReader = new FileReader(file);
            reader = new BufferedReader(fileReader);
            char[] buff = new char[4096];
            int len = 0;
            boolean readAll = offset == 0 && byteNum == 0;
            reader.skip(offset);
            while ((len = reader.read(buff)) > 0) {
                if(!readAll && byteNum < len) {
                    s.append(buff, 0, byteNum.intValue());
                    break;
                }
                s.append(buff, 0, len);
                byteNum-=len;
            }
            cleanup(reader,fileReader);
            return s.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            cleanup(reader,fileReader);
        }
        return null;
    }

    public static List<String> readAsLine(File file) throws IOException {
        return readAsLine(file, 0L, 0L);
    }

    public static List<String> readAsLine(File file, Long offsetLineNum, Long lineNum) throws IOException {
        if (file == null) {
            throw new NullPointerException("File must not be null");
        }
        if (!file.exists()) {
            throw new FileNotFoundException("File '" + file + "' does not exist");
        }
        if (file.isDirectory()) {
            throw new IOException("File '" + file + "' is a directory");
        }
        String line = null;
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(file));
            List<String> data = new ArrayList<String>();
            int countNum = 0;
            offsetLineNum = offsetLineNum == null || offsetLineNum < 0 ? 0 : offsetLineNum;
            lineNum = lineNum == null || lineNum < 0 ? 20 : lineNum;//默认20条
            boolean readAll = offsetLineNum == 0 && lineNum == 0;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if ("".equals(line)) {
                    continue;
                }
                if (readAll || (countNum >= offsetLineNum && countNum < offsetLineNum + lineNum)) {
                    data.add(line);
                }
                countNum++;
            }
            closeStream(br);
            return data;
        } catch (IOException ex) {
            throw ex;
        } finally {
            closeStream(br);
        }
    }

    public static List<String[]> readAsTable(File file, String splitRegex) throws IOException {
        return readAsTable(file, splitRegex, 0L, 0L);
    }

    public static List<String[]> readAsTable(File file, String splitRegex, Long offsetLineNum, Long lineNum) throws IOException {
        if (file == null) {
            throw new NullPointerException("File must not be null");
        }
        if (!file.exists()) {
            throw new FileNotFoundException("File '" + file + "' does not exist");
        }
        if (file.isDirectory()) {
            throw new IOException("File '" + file + "' is a directory");
        }
        String line = null;
        BufferedReader br = null;
        FileReader fileReader = null;
        try {
            fileReader = new FileReader(file);
            br = new BufferedReader(fileReader);
            List<String[]> data = new ArrayList<String[]>();
            int countNum = 0;
            offsetLineNum = offsetLineNum == null || offsetLineNum < 0 ? 0 : offsetLineNum;
            lineNum = lineNum == null || lineNum < 0 ? 20 : lineNum;//默认20条
            boolean readAll = offsetLineNum == 0 && lineNum == 0;
            while ((line = br.readLine()) != null) {
                if (readAll || (countNum >= offsetLineNum && countNum < offsetLineNum + lineNum)) {
                    data.add(line.split(splitRegex));
                }
            }
            closeStream(br);
            closeStream(fileReader);
            return data;
        } catch (IOException ex) {
            throw ex;
        } finally {
            closeStream(br);
            closeStream(fileReader);
        }
    }

    public static void closeStream(Closeable stream) {
        cleanup(stream);
    }

    public static void cleanup(Closeable... closeables) {
        for (Closeable c : closeables) {
            if (c != null) {
                try {
                    c.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String cleanXSS(String src) throws Exception {
        if(src == null) return null;
        String temp = src;
        src = src.replaceAll("<", "＜").replaceAll(">", "＞");
        src = src.replaceAll("\\(", "（").replaceAll("\\)", "）");
        src = src.replaceAll("'", "＇");
        src = src.replaceAll(";", "；");
        /**-----------------------start--------------------------*/
        src = src.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        src = src.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41");
        src = src.replaceAll("eval\\((.*)\\)", "");
        src = src.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        src = src.replaceAll("script", "");
        src = src.replaceAll("link", "");
        src = src.replaceAll("frame", "");
        /**-----------------------end--------------------------*/
        Pattern pattern = Pattern.compile("(eval\\((.*)\\)|script)",
                Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(src);
        src = matcher.replaceAll("");

        pattern = Pattern.compile("[\\\"\\'][\\s]*javascript:(.*)[\\\"\\']",
                Pattern.CASE_INSENSITIVE);
        matcher = pattern.matcher(src);
        src = matcher.replaceAll("\"\"");
        // 增加脚本
        src = src.replaceAll("script", "").replaceAll(";", "")
                .replaceAll("0x0d", "").replaceAll("0x0a", "");
        if (!temp.equals(src)) {
            throw new Exception("参数含有非法字符，已禁止继续访问！！");
        }
        return src;
    }

    public static void writeFileContent(String filepath, String newstr, boolean append) throws IOException {
        File checkFile = new File(filepath);
        FileWriter writer = null;
        try {
            if (!checkFile.exists()) {
                checkFile.createNewFile();
            }
            writer = new FileWriter(checkFile, append);
            writer.append(newstr + "\n");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != writer)
                writer.close();
        }
    }
}
